<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>生命周期（新）</title>
  <!--  引入React核心库-->
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <!--  引入react-dom,用于支持React操作Dom-->
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <!-- 引入babel，用于将jsx转为js-->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script src="https://unpkg.com/prop-types@15.6.2/prop-types.js"></script>
</head>

<body>
  <!-- 准备一个容器 -->
  <div id="root"></div>
  <script type="text/babel">
    // 1.创建一个组件
    class Count extends React.Component {
      /*  
        1.初始化阶段:由ReactDOM.render()触发---初次渲染
            1. constructor()
            2. getDerivedStateFromProps
            3. render()
            4. componentDidMount()  ====>（常用）
            一般在这个钩子中做一些初始化的事：例如开启定时器、网络请求、订阅消息
        2．更新阶段:由组件内部this.setSate()或父组件重新render触发
            1. getDerivedStateFromProps
            2. shouldComponentUpdate()
            3. render()
            4. getSnapshotBeforeUpdate
            5. componentDidUpdate()
        3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
             1. componentWillUnmount()  ====>（常用）
            一般在这个钩子中做一些收尾的事：例如关闭定时器、取消订阅
    */
      // 构造器
      constructor(props) {
        console.log('constructor');
        super(props)
        this.state = {
          count: 0
        }
      }
      // 点击+1按钮的回调
      add = () => {
        // 获取原状态
        let { count } = this.state
        count += 1
        // 更新状态
        this.setState({ count })
      }
      // 卸载组件按钮的回调
      death = () => {
        root.unmount(container)
      }
      // 强制更新按钮的回调
      force = () => {
        this.forceUpdate()
      }
      // 若state的值在任何时候都取决于props，那么可以使用getDerivedStateFromProps
      static getDerivedStateFromProps(props, state) {
        console.log('getDerivedStateFromProps');
        console.log(props, state);
        return null
      }
      // 组件挂载完毕
      componentDidMount() {
        console.log('componentDidMount--组件挂载完毕');
      }
      // 组件将要卸载
      componentWillUnmount() {
        console.log('componentWillUnmount--组件将要卸载');
      }
      // 组件是否要更新
      // 如果该钩子不写，默认会返回true，如果写了需要返回一个布尔值 true 或 false
      shouldComponentUpdate() {
        // 需要返回一个布尔值 true 或 false
        console.log('shouldComponentUpdate--组件是否要更新');
        return true
      }
      // 在更新之前获取快照
      getSnapshotBeforeUpdate() {
        console.log('getSnapshotBeforeUpdate')
        return '快照值'
      }
      // 组件更新完毕
      componentDidUpdate(preProps, preState, snapShot) {
        console.log('componentDidUpdate--组件更新完毕', preProps, preState, snapShot);
      }
      // render调用时机：初始化渲染，状态更新之后
      render() {
        console.log('render--组件渲染');
        const { count } = this.state
        return (
          <div>
            <h1>当前求和为：{count}</h1>
            <button onClick={this.add}>点我+1</button>
            <button onClick={this.death}>卸载组件</button>
            <button onClick={this.force}>不更改状态中的任何数据强制更新一下</button>
          </div>
        )
      }
    }
    // 2.渲染组件到页面
    const container = document.getElementById('root')
    const root = ReactDOM.createRoot(container)
    root.render(<Count name='tom' />)
  </script>
</body>

</html>